package Default;

import java.awt.BorderLayout;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileReader;
import java.security.AllPermission;
import java.util.ArrayList;
import java.util.Random;
import java.util.StringTokenizer;

import javax.swing.JFrame;
import javax.swing.JPanel;

import world.Target;
import world.Time;
import world.World;


public class Manager {

	JFrame frame=null;
	ArrayList<Agent> superNodes=null;
	public ArrayList<Agent> all_agents=null;
	Routing routing=null;

	
	
	/**
	 * 
	 *  temp
	 * 
	 */
	Target target=null;
	Agent agent=null;
	public static int cntCenter=0;
	public static int cntAgents=0;
	

	int cnt=0;
	
	public Manager()
	{
		Variables.x=200;//limit 800
		Variables.y=200;//100;//limit 400
		Variables.num_of_agents=3500;//1900;//limit 12900
		Variables.gridZoom=4;//limit 2
		Variables.battery_Size=400;
		Variables.sense_radius=5;//5;
		routing=new Routing(this);
		Variables.sensorsMapFileName=new String("myNetworkFile2");
		Variables.targetsFileName=new String("myTargetsFile2");
		Variables.gridSizeX=Variables.x+Variables.sense_radius*2;
		Variables.gridSizeY=Variables.y+Variables.sense_radius*2;
		Variables.grid=new int[Variables.gridSizeY][Variables.gridSizeX];
		
	}
	public Manager(int _x,int _y,int num,int _zoom,double _energy,int _radius)
	{
		Variables.x=_x;
		Variables.y=_y;
		Variables.num_of_agents=num;
		Variables.gridZoom=_zoom;
		Variables.battery_Size=_energy;
		Variables.sense_radius=_radius;
		routing=new Routing(this);
	}
	public void init()
	{
		//envi=new Environment(this,x,y,numOfSensors,zoom);
		//Agent.envi=envi;
		//Agent.sense_radius=Variables.sense_radius;
		/*for(int i=0;i<gridSizeY;i++)
		{
			for(int j=0;j<gridSizeX;j++)
				System.out.print(envi.grid[i][j]+" ");
			System.out.println();
		}*/
		/*Variables.gridSizeX=Variables.x+Variables.sense_radius*2;
		Variables.gridSizeY=Variables.y+Variables.sense_radius*2;
		Variables.grid=new int[Variables.gridSizeY][Variables.gridSizeX];*/
		try{
		BufferedReader in =new BufferedReader(new FileReader(Variables.sensorsMapFileName+".txt"));
		String line=in.readLine();
		//System.out.println(line);
		StringTokenizer tokens=new StringTokenizer(line);
		//set the centrals sensors (black) 
		Variables.center=new Agent(0,0,0,0);
		superNodes=new ArrayList<Agent>();
		superNodes.add(new Agent(/*envi,*/-1,Variables.gridSizeX/2,Variables.gridSizeY/2,Variables.battery_Size));
		//superNodes.add(new Agent(/*envi,*/-1,Variables.gridSizeX/4,Variables.gridSizeY/4,Variables.energy));
		//centers.add(new Agent(/*envi,*/-2,Variables.gridSizeX/4*3,Variables.gridSizeY/4,Variables.energy));
		//centers.add(new Agent(/*envi,*/-3,Variables.gridSizeX/4,Variables.gridSizeY/4*3,Variables.energy));
		//centers.add(new Agent(/*envi,*/-4,Variables.gridSizeX/4*3,Variables.gridSizeY/4*3,Variables.energy));
		
		// set all the sensors (red)
		int id=1;
		//Random rand=new Random();
		int randX, randY;
		all_agents=new ArrayList<Agent>();
		Agent tmp_agent;
		for(int i=0;i<Variables.num_of_agents;i++)
		{
			//do{
				randX=Integer.parseInt(tokens.nextToken());
				randY=Integer.parseInt(tokens.nextToken());
			//}while(Variables.grid[randY][randX]!=0);
			tmp_agent=new Agent(/*envi,*/id,randX,randY,Variables.battery_Size);
			all_agents.add(tmp_agent);
			id++;
			
			
			//tmp_agent.data_list.add(new Data(id,0));
			
		}
		
		//System.out.println("avg of neighbors "+countNeighbors());

		/*for(int i=0;i<Variables.gridSizeY;i++)
		{
			for(int j=0;j<Variables.gridSizeX;j++)
			{
				//System.out.print(envi.grid[i][j]+" ");
				if(Variables.grid[i][j]!=0)
					System.out.print(Variables.grid[i][j]);
				else
					System.out.print("0");
			}
			System.out.println();
		}*/
		
		setConnection();
		in.close();
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	/**
	 * @param args
	 */
	
	
	public void setConnection()
	{
		routing.setConnectionsNaive(/*envi*/);
		//routing.setConnectionsNaiveDynamic(/*envi*/);
		//routing.setConnectionsDijkstra(/*envi*/);
		//routing.setConnectionsClustering();
		routing.setChildren();
	}
	public double countNeighbors()
	{
		double count=0;
		int my_x,my_y;
		for(int i=0;i<all_agents.size();i++)
		{
			my_x=all_agents.get(i).position.x;
			my_y=all_agents.get(i).position.y;			
			for(int j=0;j<all_agents.size();j++)
			{
				if(i!=j)//don't count me
				{
					if( Math.sqrt(Math.pow(Math.abs(my_x-all_agents.get(j).position.x),2)+Math.pow(Math.abs(my_y-all_agents.get(j).position.y),2))<=Variables.sense_radius*2)
						count++;
				}
			}
		}
		return count/Variables.num_of_agents;
	}
	
	public void startSensorsFrame()
	{
		frame=new JFrame("Sensors Network");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocation(5,40);
		frame.setLayout(new BorderLayout());
		SensorsPanel panel=new SensorsPanel(/*envi,*/this);
		//panel.p
		frame.add(panel,"Center");
		
		//frame.setBounds(30, 90, 700, 450);
		frame.pack();
		frame.setVisible(true);
		
	}

	public boolean actAllagents()
	{
		boolean rerouting=false;
		for(int i=0;i<all_agents.size();i++)
		{
			if(all_agents.get(i).actTimeStep())
				cnt++;
		}
		if(cnt>0)
		{
			rerouting=true;
			cnt=0;
		}
		return rerouting;
	}
	
	public void nextTimeAllagents()
	{
		for(int i=0;i<all_agents.size();i++)
		{
			all_agents.get(i).nextTimeStep();
		}
	}
	
	public boolean timeStep()
	{
		boolean rerouting=false,stop=false;
		if(actAllagents())
			rerouting=true;
		nextTimeAllagents();
		if(rerouting)
		{
			stop=routing.reConnectionsNaive();
			routing.clearChildren();
			routing.setChildren();
		}
		return stop;
	}
	
	public void showBattey()
	{
		Agent agent;
		/*for(int i=0;i<all_agents.size();i++)
		{
			agent=all_agents.get(i);
			if(agent.battery>0)
				System.out.println(agent.ID+" : "+agent.battery);
			
		}*/
		//frame.repaint();
		JFrame resultFrame=new JFrame();
		resultFrame=new JFrame("Sensors Network");
		resultFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		resultFrame.setLocation(5,40);
		resultFrame.setLayout(new BorderLayout());
		ResultPanel panel=new ResultPanel(this);
		//panel.p
		resultFrame.add(panel,"Center");
		
		//frame.setBounds(30, 90, 700, 450);
		resultFrame.pack();
		resultFrame.repaint();
		resultFrame.setVisible(true);
	}
	

	// read from file
	
	public static void main(String[] args) {
		
		Time time=new Time();
		Manager manager=new Manager();
		Variables.manager=manager;
		int total_time=400;//101;//2000;
		
		manager.init();

		manager.frame.repaint();
		
		
		World world=new World();
		world.startWorldFrame();
		world.frame.repaint();
		
		world.openFileRead();
		
		

		manager.frame.repaint();

		boolean stop=false;
		do{
		//for(int z=0;z<total_time;z++)
		//{
			try{
				Thread.sleep(10);
			
				stop=manager.timeStep();
				manager.frame.repaint();
				//if(z<total_time-100)
				{
					world.generateTargets();
					
					world.timeStep();
					world.frame.repaint();
				}
				time.nextTimeStep();
				
			}catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		//}
		}while(!stop);
		for(int z=0;z<300;z++)
		{
			try{
				Thread.sleep(10);
			
				stop=manager.timeStep();
				manager.frame.repaint();
				
				time.nextTimeStep();
				
			}catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
		world.closeFile();
		
		System.out.println("end. Center: "+Manager.cntCenter+" Agents: "+Manager.cntAgents);
		System.out.println("end. total recieve data didn't send: "+Agent.cntTemp);
		

		manager.showBattey();
	}


	
	// generate new files
/*	
	public static void main(String[] args) {
 
		
		Time time=new Time();
		Manager manager=new Manager();
		Variables.manager=manager;
		int total_time=2000;
		 
		 //for generating new network add this lines
		
		System.out.println("hi, start generating new network");
		GenerateSensorsMap generate=new GenerateSensorsMap();
		generate.generateSensorsMap(Variables.sensorsMapFileName);
		System.out.println("end");
		
		manager.init();

		manager.frame.repaint();
		
		
		World world=new World();
		world.startWorldFrame();
		world.frame.repaint();
		
		//world.openFileRead();
		
		 // for generating new targets add this line and remove the above
		 
		world.openFileWrite();
		

		manager.frame.repaint();

		boolean stop=false;
		do{
		//for(int z=0;z<total_time;z++)
		//{
			try{
				Thread.sleep(10);
			
				stop=manager.timeStep();
				manager.frame.repaint();
				if(z<total_time-100)
				{
					//world.generateTargets();
					
					// for generating new targets add this line and remove the above
					
					world.generateTargetsToFile();
					world.timeStep();
					world.frame.repaint();
				}
				time.nextTimeStep();
				
			}catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		//}
		}while(!stop);
		for(int z=0;z<100;z++)
		{
			try{
				Thread.sleep(10);
			
				stop=manager.timeStep();
				manager.frame.repaint();
				
				time.nextTimeStep();
				
			}catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
		
		world.closeFile();
		
		System.out.println("end. Center: "+Manager.cntCenter+" Agents: "+Manager.cntAgents);

		manager.showBattey();

	}	
*/
}
